package jinyilw.tools.net.dev;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import java.security.spec.KeySpec;

public class DataEncryption implements DataManipulator
{
	public static final int DESEDE_ENCRYPTION_SCHEME = 1;
	public static final int DES_ENCRYPTION_SCHEME = 2;

	private final Cipher encryption;
	private final Cipher decryption;

	public DataEncryption(int encryptionScheme, String encryptionKey)
	{
		try
		{
			String unicodeFormat = "UTF8";
			byte[] keyBytes = encryptionKey.getBytes(unicodeFormat);

			String scheme;
			KeySpec keySpec;

			switch (encryptionScheme)
			{
				case DESEDE_ENCRYPTION_SCHEME:
					scheme = "DESede";
					keySpec = new DESedeKeySpec(keyBytes);
					break;

				case DES_ENCRYPTION_SCHEME:
					scheme = "DES";
					keySpec = new DESKeySpec(keyBytes);
					break;

				default:
					throw new IllegalArgumentException(
							"Encryption scheme is not supported.");
			}

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(scheme);
			SecretKey key = keyFactory.generateSecret(keySpec);

			// the encryption cipher
			this.encryption = Cipher.getInstance(scheme);
			this.encryption.init(Cipher.ENCRYPT_MODE, key);

			// the decryption cipher
			this.decryption = Cipher.getInstance(scheme);
			this.decryption.init(Cipher.DECRYPT_MODE, key);

		} catch (Exception ex)
		{
			throw new RuntimeException(ex);
		}
	}

	public DataEncryption()
	{
		this(DataEncryption.DESEDE_ENCRYPTION_SCHEME,
				"Secure Network Data Packet with Encryption Key");
	}

	public byte[] manipulate(byte[] data) throws Exception
	{
		return this.encryption.doFinal(data);
	}

	public byte[] deManipulate(byte[] data) throws Exception
	{
		return this.decryption.doFinal(data);
	}

}
